﻿using System;
using System.IO;
using System.Speech.Recognition;
using System.Windows;
using Microsoft.Research.Kinect.Audio;

namespace Kinect
{ 
    public class SpeechText:EventArgs
        {
            public String x;
            public SpeechText(String y)
            {
                x = y;
            }
       }
    public partial class KinectController
    {
         #region SpeechRebognizer

        private KinectAudioSource kinectSource;
        public SpeechRecognitionEngine sre;

       

        public delegate void outSpeechRecognizedHandle(object sender, SpeechText args);
        public delegate void outSpeechRecognitionRejectedHandle(object sender, SpeechRecognitionRejectedEventArgs args);
        public delegate void outSpeechHypothesizedHandle(object sender, SpeechHypothesizedEventArgs args);
        static public outSpeechRecognizedHandle OutSpeechRecognized;
        static public outSpeechRecognitionRejectedHandle OutSpeechRecognitionRejected;
        static public outSpeechHypothesizedHandle OutSpeechHypothesized;

        public void InitSpeechRecognizer()
        {
            RecognizerInfo ri = GetKinectRecognizer();

            if (ri == null)
            {
                MessageBox.Show("Could not find Kinect speech recognizer. Please refer to the sample requirements.");
                return;
            }

            try
            {
                sre = new SpeechRecognitionEngine(ri.Id);
            }
            catch
            {
                MessageBox.Show("There was a problem initializing Speech Recognition.Ensure you have the Microsoft Speech SDK installed and configured.");
                return;
            }
                
            var orders = new Choices();
            orders.Add("书写");
            orders.Add("清除");
            orders.Add("结束");

            var gb = new GrammarBuilder();
            //Specify the culture to match the recognizer in case we are running in a different culture.                                 
            gb.Culture = ri.Culture;
            gb.Append(orders);


            // Create the actual Grammar instance, and then load it into the speech recognizer.
            var g = new Grammar(gb);

            sre.LoadGrammar(g);
            sre.SpeechRecognized += SreSpeechRecognized;
            sre.SpeechHypothesized += SreSpeechHypothesized;
            sre.SpeechRecognitionRejected += SreSpeechRecognitionRejected;
            sre.SpeechDetected += new EventHandler<SpeechDetectedEventArgs>(sre_SpeechDetected);

            try
            {
                kinectSource = new KinectAudioSource();
                kinectSource.FeatureMode = true;
                kinectSource.AutomaticGainControl = false;
                kinectSource.SystemMode = SystemMode.OptibeamArrayOnly;
                kinectSource.MicArrayMode = MicArrayMode.MicArrayAdaptiveBeam;

                Stream s = kinectSource.Start();
                //sre.SetInputToAudioStream(s, new SpeechAudioFormatInfo(
                //                                EncodingFormat.Pcm, 16000, 16, 1,
                //                                32000, 2, null));
                sre.SetInputToDefaultAudioDevice();
                sre.RecognizeAsync(RecognizeMode.Multiple);
            }
            catch
            { 
                MessageBox.Show("There was a problem initializing the KinectAudioSource.Ensure you have the Kinect SDK installed correctly.");
                return;
            }
        }

        void sre_SpeechDetected(object sender, SpeechDetectedEventArgs e)
        {
        //    MessageBox.Show(e.t);
            //throw new NotImplementedException();
        }
        private static RecognizerInfo GetKinectRecognizer()
        {
            //Func<RecognizerInfo, bool> matchingFunc = r =>
            //{
            //    string value;
            //    r.AdditionalInfo.TryGetValue("Kinect", out value);
            //    return "True".Equals(value, StringComparison.InvariantCultureIgnoreCase)
            //        && "en-US".Equals(r.Culture.Name, StringComparison.InvariantCultureIgnoreCase);
            //};
            return SpeechRecognitionEngine.InstalledRecognizers()[0];
        }
        static void SreSpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
        {
            //if (e.Result != null)
            //    DumpRecordedAudio(e.Result.Audio);
            if ( OutSpeechRecognitionRejected  != null)
            {
                OutSpeechRecognitionRejected(sender,e);
            }
        }

        static void SreSpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        {
            if (OutSpeechHypothesized != null)
            {
                OutSpeechHypothesized(sender,e);
            }
           //  MessageBox.Show("Speech Hypothesized: \t{0}", e.Result.Text);
        }
        static void SreSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            if (e.Result.Confidence < 0.985)
                return;
            //This first release of the Kinect language pack doesn't have a reliable confidence model, so 
            //we don't use e.Result.Confidence here.
            //Console.WriteLine("\nSpeech Recognized: \t{0}", e.Result.Text);
            if (OutSpeechRecognized != null)
            {
                SpeechText x = new SpeechText(e.Result.Text);
                OutSpeechRecognized(sender,x);
            }
            //MessageBox.Show(e.Result.Text);
        }

       
        private void SpeechRecognizerExit()
        {
            if (kinectSource != null)
            {
                kinectSource.Stop();
                sre.RecognizeAsyncCancel();
                sre.RecognizeAsyncStop();
                kinectSource.Dispose();
            }
        }
    }
        #endregion 
}
